package com.wang.jmonkey.interceptor;

import com.wang.jmonkey.common.annotation.Log;
import com.wang.jmonkey.common.constant.RabbitConstant;
import com.wang.jmonkey.interceptor.handler.result.ExceptionResultHandlerManager;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.support.GenericApplicationContext;

import java.lang.reflect.Method;

/**
 * @Description 日志拦截器
 * @Author HeJiawang
 * @Date 2021/5/20 13:08
 */
@Slf4j
public class LogInterceptor implements MethodInterceptor {

    private RabbitTemplate rabbit;

    private GenericApplicationContext context;

    public LogInterceptor(RabbitTemplate rabbit,GenericApplicationContext context) {
        this.rabbit = rabbit;
        this.context = context;
    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {

        try {
            Method method = invocation.getMethod();
            Log logAnnotation = method.getAnnotation(Log.class);

            rabbit.convertAndSend(RabbitConstant.EXCHANGE_LOG, RabbitConstant.QUEUE_LOG_HANDLE, logAnnotation.value());
        } catch (Exception e) {

            log.error(this.getClass().getName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName(), e);
        } finally {

            try {

                return invocation.proceed();
            } catch (Throwable e) {
                log.error(this.getClass().getName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName(), e);

                ExceptionResultHandlerManager manager = this.context.getBean(ExceptionResultHandlerManager.class);
                return manager.result(invocation.getMethod().getReturnType(), e.getMessage(), manager);
            }
        }
    }
}
